﻿using System;
using javacli;
using System.Reflection;
using System.Diagnostics;
using System.Threading;

namespace j2c
{
    public class Entry
    {
        static string dir;
        internal static TraceSource log = new TraceSource("Entry");
        static Entry()
        {
            log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, "Begin static constructor");
            log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, "CLR version: {0}", Environment.Version);
            log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, "If is running as an x64 exe, size of the pointers = 8, else 4. The Size of the pointers: {0}", IntPtr.Size);

            string location = Assembly.GetExecutingAssembly().Location;
            char[] separators = { '\\' };
            int lastindex = location.LastIndexOfAny(separators);
            dir = location.Substring(0, lastindex + 1);
        }
        public static void initFromJvm(IntPtr env, IntPtr classz)
        {
            log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, "Begin Entry.initFromJvm");
            AppDomain.CurrentDomain.AssemblyResolve += FindAssembly;
            AssemblyLoader.initFromJvm(env, classz);
        }

        public static Assembly FindAssembly(object sender, ResolveEventArgs args)
        {
            log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, "Begin FindAssembly");

            Assembly a = null;
            try
            {
                
                AssemblyName assemblyname = new AssemblyName(args.Name);

                if (assemblyname != null && assemblyname.Name == "javacli")
                {
                    log.TraceEvent(TraceEventType.Verbose, Thread.CurrentThread.ManagedThreadId, dir + assemblyname.Name + ".dll");
                    a = Assembly.LoadFrom(dir + assemblyname.Name + ".dll");
                }
                else
                {
                    if (assemblyname != null) log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, assemblyname.Name + " not found!");
                }
            }
            catch (Exception e)
            {
                log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, "Exception : " + e.GetType() + " " + e.Message);
            }
            return a;
        }
    }

    public class AssemblyLoader
    {
        public static void initFromJvm(IntPtr env, IntPtr classz)
        {
            try
            {
                FromJava.initFromJvm(env, classz);
            }
            catch (Exception e)
            {
                Entry.log.TraceEvent(TraceEventType.Information, Thread.CurrentThread.ManagedThreadId, e.GetType() + " : " + e.Message);
            }
        }
        public static IntPtr StringToArray(IntPtr env, IntPtr classz, IntPtr jstring)
        {
            return FromJava.StringToArray(env, classz, jstring);
        }

    }
}
